#include "web_handler.h"

#include <time.h>

void handler::web_handler::handle_event(boost::shared_ptr<network::event> n)
{
	boost::shared_ptr<model::dom> node(n->node);
	if(node->name() == "play") {
		do_play(node);
	} else if(node->name() == "list") {
		do_list(node);
	} else if(node->name() == "pause") {
		do_pause(node);
	} else if(node->name() == "list_temp") {
		do_temp(node);
	} else if(node->name() == "light") {
		do_light(node);
	} else if(node->name() == "tv") {
		do_tv(node);
	}
}

void handler::web_handler::do_pause(boost::shared_ptr<model::dom> node)
{
	string clt = node->find_attrib("client");
	model::client *ptr = find_client(clt);
	boost::shared_ptr<network::i_socket> sock(
		find_socket(ptr));
	boost::shared_ptr<network::pause> pause(new network::pause(
		network::singletone<network::configurator>::instance()->
			get_web_send_impl()));
	sock->send(pause->get_string());
}

void handler::web_handler::do_list(boost::shared_ptr<model::dom> node)
{
	// handle list-commands
	// optain lock
	boost::shared_ptr<boost::mutex> mon(
		network::singletone<model::model_class>::get_monitor());
	boost::shared_ptr<model::model_class> model(
		network::singletone<model::model_class>::instance());

	boost::mutex::scoped_lock l(*mon);
	network::model_send snd(network::singletone<network::configurator>
			::instance()->get_web_send_impl(), model);
	_sock->send(snd.get_string());
}

model::client* handler::web_handler::find_client(const string &str)
{
	model::client *ptr = 0;

	boost::shared_ptr<boost::mutex> mon(
		network::singletone<model::model_class>::get_monitor());
	boost::shared_ptr<model::model_class> model(
		network::singletone<model::model_class>::instance());

	boost::mutex::scoped_lock l(*mon);
	ptr = model->find_client(str);
	return ptr;
}

model::title* handler::web_handler::find_title(const string &file, 
						model::client *clt)
{
	model::title *ptr = 0;

	boost::shared_ptr<boost::mutex> mon(
		network::singletone<model::model_class>::get_monitor());
	boost::shared_ptr<model::model_class> model(
		network::singletone<model::model_class>::instance());

	boost::mutex::scoped_lock l(*mon);
	ptr = model->find_title(file, clt);
	return ptr;
}

void handler::web_handler::send_play(boost::shared_ptr<model::client> clt,
				     boost::shared_ptr<model::title> title)
{
	boost::shared_ptr<network::i_socket> sock(
		find_socket(clt.get()));

	boost::shared_ptr<network::play> play(new network::play(
		network::singletone<network::configurator>::instance()->
			get_web_send_impl(), title, clt));
	sock->send(play->get_string());
	// write it into logfile!
	handler::file_streamer streamer(clt->get_name() + ".txt");
	streamer.append_title(title);
}

void handler::web_handler::do_play(boost::shared_ptr<model::dom> node)
{
	string clt = node->find_attrib("client");
	string file = node->find_attrib("file");
	string random = node->find_attrib("random");

	if(random == "random") {
		cout << "doing random..." << endl;
		do_random(clt, file);
		return;
	}
	
	// handle play-commands
	model::client *ptr = find_client(clt);
	model::title *title = find_title(file, ptr);
	if(ptr == 0) return;
	// send the play-message to the corresponding server
	boost::shared_ptr<network::i_socket> sock(
		find_socket(ptr));
	boost::shared_ptr<model::title> ptr_t(title, core::null_deleter());
	boost::shared_ptr<model::client> ptr_c(ptr, core::null_deleter());
	send_play(ptr_c, ptr_t);
}

void handler::web_handler::do_random(const string &client, const string &file)
{
	model::client *clt = find_client(client);
	boost::shared_ptr<model::client> ptr(clt, core::null_deleter());
	handler::data_miner miner(ptr);
	miner.doit();
	boost::shared_ptr<model::title> result(miner.get_result());
	if(result.get() == 0) {
		return;
	}
	cout << result->get_title() << " " << result->get_filename() << endl;
	send_play(ptr, result);
	boost::shared_ptr<network::play> play(new network::play(
		network::singletone<network::configurator>::instance()->
			get_web_send_impl(), result, ptr));
	_sock->send(play->get_string());
}

void handler::web_handler::do_temp(boost::shared_ptr<model::dom> node)
{
	boost::shared_ptr<network::temperature> temp(new network::temperature(
		network::singletone<network::configurator>::instance()->
			get_rs232_send_impl()));
	_controller->send(temp->get_string());
}

void handler::web_handler::do_light(boost::shared_ptr<model::dom> node)
{
	boost::shared_ptr<network::light> light(new network::light(
		network::singletone<network::configurator>::instance()->
			get_rs232_send_impl(), node->find_attrib("signal")));
	_controller->send(light->get_string());
}

void handler::web_handler::do_tv(boost::shared_ptr<model::dom> node)
{
	boost::shared_ptr<network::tv> tv(new network::tv(
		network::singletone<network::configurator>::instance()->
			get_rs232_send_impl(), node->find_attrib("signal")));
	_controller->send(tv->get_string());
}

boost::shared_ptr<network::i_socket> 
	handler::web_handler::find_socket(const model::client *c) const
{
	boost::shared_ptr<network::network_client> map(
		network::singletone<network::network_client>::instance());

	typedef network::network_client::iterator it;
	for(it i = map->begin(); i != map->end(); ++i) {
		if(i->second == c) {
			return i->first;
		}
	}
	return boost::shared_ptr<network::i_socket>();
}

void handler::web_handler::notify(const network::notifier *n)
{
	// since the web-handler holds no data, it doesn't need to 
	// delete anything
	boost::shared_ptr<handler::web_handler> tmp(_this.lock());
	fire_listener();
}

